package com.example.springboot.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.example.springboot.controller.request.BaseRequest;
import com.example.springboot.entity.Order;
import com.example.springboot.entity.Products;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.OrderMapper;
import com.example.springboot.mapper.ProductsMapper;
import com.example.springboot.mapper.UserMapper;
import com.example.springboot.mapper.po.ProductSalesPO;
import com.example.springboot.service.IOrderService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class OrderService implements IOrderService {

    @Autowired //通过autowired导入orderMapper
    OrderMapper orderMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    ProductsMapper productsMapper;

    public List<Order> list(){
        return orderMapper.list();
    }

    @Override
    public PageInfo<Order> page(BaseRequest baseRequest){
//        dependency引入pagehelper
//        PageHelper传入页面和每页信息条数
        PageHelper.startPage(baseRequest.getPageNum(),baseRequest.getPageSize());
        List<Order> orders=orderMapper.listByCondition(baseRequest);
        return new PageInfo<>(orders);
    }

    @Override
    public void save(Order order){//        当做卡号来处理 products的库存
        Date date= new Date();
        //订单是一张合成表,涉及到产品和用户
        System.out.println("order内容是"+order.getTotalPrice());
//        1.获取用户信息
        String userName= order.getUserName();
        User user = userMapper.getByUserName(userName);//获取用户信息
        if(Objects.isNull(user)){
            throw new ServiceException("用户不存在");
        }
//        2.获取产品库存量是否足够
        Products products = productsMapper.getByProductsName(order.getProductName());
        if(Objects.isNull(products)){
            throw new ServiceException("产品不存在");
        }
//        3.校验产品数量是否不足
        if((products.getInventory()-order.getNumber())< 0){
            throw new ServiceException("产品数量不足");
        }

//        4.校验账户余额是否足够:余额>产品单价 * 数量
        if((user.getMoney()-order.getTotalPrice())<0){
            throw new ServiceException("账户余额不足");
        }
//        5.更新账户余额 账户余额减少
        user.setMoney(user.getMoney()-order.getTotalPrice());
        userMapper.updateById(user);

//        6.更新产品库存信息 月销量
        products.setInventory(products.getInventory()-order.getNumber());//如果库存为0,则不能进行产品购买
        products.setSales(order.getNumber()+products.getSales());
        productsMapper.updateById(products);

//        7.新增订单记录 新增订单名称
        order.setOrderNum(DateUtil.format(date,"yyyyMMdd")+user.getId()+products.getId()+order.getId());
        order.setCover(products.getCover());
        order.setNickName(user.getNickName());
        orderMapper.save(order);
//     通过hashCode编码将fastSimpleUUID产生的字母和数字转为数字

    }


    @Override
    public Order getById(Integer id) {
        return orderMapper.getById(id);
    }

    @Override
    public Order getByUserName(String userName) {
        return orderMapper.getByUserName(userName);
    }

    @Override
    public void update(Order order) {
        order.setUpdateTime(new Date());
        orderMapper.updateById(order);

    }

    @Override
    public void deleteById(Integer id) {
        orderMapper.deleteById(id);
    }

//    获取对应的时间下的数据
    @Override
    public Map<String,Object> getCountByTimeRange(String timeRange){
        Map<String,Object> map=new HashMap<>();
        Date today = new Date();
        List<DateTime> dateRange; //获取时间数据
        switch (timeRange){
            case "week":
//                返回过去一周的数据 offsetDay 计算时间的工具方法
                dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today,-6),today, DateField.DAY_OF_WEEK);
                break;
            case "month":
                dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today,-29),today, DateField.DAY_OF_MONTH);
                break;
            case "month2":
                dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today,-59),today, DateField.DAY_OF_MONTH);
                break;
            case "month3":
                dateRange = DateUtil.rangeToList(DateUtil.offsetDay(today,-89),today, DateField.DAY_OF_MONTH);
                break;
            default:
                dateRange = new ArrayList<>();
        }
//        自定义函数 datetimeToDateStr 把DateTime类型的List转为一个String的List
        List<String> dateStrRange  = datetimeToDateStr(dateRange);
        map.put("date",dateStrRange);//x轴的日期数据生产完毕
//        // timeRange = week month
        //getCountByTimeRange不会统计数据库没有的数据,比如 11.4没有,不会返回date=2023-11-04,count=0这个数据
        List<ProductSalesPO> salesCount = orderMapper.getSalesByTimeRange(timeRange);//里面含有销量 总价 日期三个值
        map.put("sales",countList(salesCount,dateStrRange));
        map.put("prices",pricesList(salesCount,dateStrRange));
        return map;
    }

    //把DateTime类型的List转换为一个String的List
    private List<String> datetimeToDateStr(List<DateTime> dateTimeList){
        List<String> list = CollUtil.newArrayList();
        if(CollUtil.isEmpty(dateTimeList)){
            return list;
        }
        for(DateTime dateTime : dateTimeList){
            String date = DateUtil.formatDate(dateTime);
            list.add(date);
        }
        return list;
    }

    //  对数据库未统计的时间进行处理
    private List<Integer> countList(List<ProductSalesPO> countPOList,List<String> dateRange){
        List<Integer> list = CollUtil.newArrayList();
        if(CollUtil.isEmpty(countPOList)){
            return list;
        }
        for(String date : dateRange){
            //.map(BorrowReturCountPO::getCount)取出对象里的count值
            // orElse(0)对没有匹配的数据返回0
            //2023-11-04没有的话 就返回0
            Integer count =countPOList.stream().filter(countPO -> date.equals(countPO.getDate()))
                    .map(ProductSalesPO ::getCount).findFirst().orElse(0);
            list.add(count);
        }
        //最后返回的list的元素个数会跟dateRange的元素个数完全一样
        return list;
    }

    private List<Integer> pricesList(List<ProductSalesPO> countPOList,List<String> dateRange){
        List<Integer> list = CollUtil.newArrayList();
        if(CollUtil.isEmpty(countPOList)){
            return list;
        }
        for(String date : dateRange){
            //.map(BorrowReturCountPO::getCount)取出对象里的count值
            // orElse(0)对没有匹配的数据返回0
            //2023-11-04没有的话 就返回0
            Integer prices =countPOList.stream().filter(countPO -> date.equals(countPO.getDate()))
                    .map(ProductSalesPO ::getPrices).findFirst().orElse(0);
            list.add(prices);
        }
        //最后返回的list的元素个数会跟dateRange的元素个数完全一样
        return list;
    }
}
